home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-07-29 | 4.1 KB | 151 lines | [TEXT/sade] |
- # Symbolic Application Debugging Environment 1.3 Final
- #
- # Copyright Apple Computer, Inc. 1987-1991
- # All rights reserved.
-
- ###############################################################################
-
-
- define __ROMlo__, __ROMhi__ # ROM boundaries
- define __heapLo__, __heapHi__ # heap boundaries
- define __stackLo__, __stackHi__ # stack boundaries
-
-
- # Inits stuff and makes sure stack is OK before we try to crawl it.
- func InitSC7()
- __stackLo__ := A7
- __stackHi__ := CurStackBase
- __heapLo__ := ApplZone
- __heapHi__ := ApplLimit
- __ROMlo__ := RomBase & TargetAddrMask
- __ROMhi__ := __ROMlo__ + $40000 # assume 256K ROM- need a better way!!!
- if (__stackLo__ & 1) or (__stackHi__ & 1) then
- return 0
- end
- if (A7 > __stackHi__) then
- return 0
- end
- return 1
- end
-
- # Returns 1 if addr is in application heap or ROM.
- func IsCodeAddr(addr)
- addr := unsignedlong(addr & TargetAddrMask)
- if (addr >= __heapLo__) and (addr <= __heapHi__) then # in heap
- return 1
- elseif (addr >= __ROMlo__) and (addr <= __ROMhi__) then # in ROM
- return 1
- end
- return 0
- end
-
- # Is addr the return address to somewhere?
- # This function checks whether the location immediately before
- # addr contains a JSR, BSR, or A-trap, and if so returns the
- # address of that instruction. Otherwise it returns 0.
- func ReturnAddress(addr)
- define instr, callAddr
- addr := unsignedlong(addr & TargetAddrMask)
- # check if addr is in an executable region
- if not IsCodeAddr(addr) then
- return 0 # not in heap (or ROM)
- end
- callAddr := unsignedlong(addr - 2)
- if not IsCodeAddr(callAddr) then
- return 0
- end
- instr := ^unsignedword(callAddr)^
- if instr = $6100 then
- return callAddr # BSR with byte displacement
- elseif (instr & $FFF8) = $4E90 then
- return callAddr # JSR (An)
- elseif (instr & $F000) = $A000 then
- return callAddr # A-trap
- end
- callAddr := unsignedlong(addr - 4)
- if not IsCodeAddr(callAddr) then
- return 0
- end
- instr := ^unsignedword(callAddr)^
- if instr = $6100 then
- return callAddr # BSR with word displacement
- elseif (instr & $FFF8) = $4EA8 then
- return callAddr # JSR (disp, An)
- elseif (instr & $FFF8) = $4EB0 then
- return callAddr # JSR (disp, An, Dn)
- elseif instr = $4EBA then
- return callAddr # JSR (disp, PC)
- elseif instr = $4EBB then
- return callAddr # JSR (disp, PC, Dn)
- elseif instr = $4EB8 then
- return callAddr # JSR (xxxx).W
- end
- callAddr := unsignedlong(addr - 6)
- if not IsCodeAddr(callAddr) then
- return 0
- end
- instr := ^unsignedword(callAddr)^
- if instr = $4EB9 then
- return callAddr # JST (xxxx).L
- end
- return 0 # not a return addr
- end
-
- # Does addr seem to point to an A6 link value?
- # We check that addr is even, within the stack boundaries, and between
- # the actual A6 and previous A6 values (or, of course, that it actually
- # points to the previous A6!).
- func A6Link(addr, prevA6)
- if (addr & 1) or (addr < __stackLo__) or (addr > __stackHi__) then
- return 0
- end
- if (^unsignedlong(addr)^ = prevA6) then
- return 1
- end
- if (addr < A6) or (addr < prevA6) then
- return 0
- end
- return 1
- end
-
- # Try stack addresses from CurStackBase down to current A7.
- # For each that looks like a return address, display it and
- # check the preceding value to see if it looks like an A6 link.
- proc ShowFrame(prevA6, thisA7)
- define name
- define maybeA6loc := thisA7 - 4 # might be an A6 link value here
- define nextA7 := thisA7 - 2 # check on word boundaries
- define callAddr := ReturnAddress(^unsignedlong(thisA7)^)
- if callAddr <> 0 then
- printf "$%.8X ", long(thisA7)
- if A6Link(maybeA6loc, prevA6) then
- printf "$%.8X ", long(maybeA6loc)
- prevA6 := maybeA6loc
- else
- printf " "
- end
- name := where(callAddr)
- if copy(name, 1, 1) = '$' then
- name := ''
- end
- printf "$%.8X %s\n", long(callAddr), name
- end
- if nextA7 >= A7 then
- ShowFrame(prevA6, nextA7)
- end
- end
-
- # The main entry point.
- proc StackCrawl7
- CheckNullTarget
- if not InitSC7() then
- alert "Damaged stack:\nA7 must be even and <= CurStackBase."
- abort
- end
- printf "Return addresses on the stack\n"
- printf "Stack Addr Frame Addr Caller\n"
- ShowFrame(0, CurStackBase - 4)
- end
-
- macro sc7 'StackCrawl7'
-